﻿Imports IICModel

Imports System.Reflection

Namespace PeriodProcessing

    ''' <summary>
    ''' Temporary holder class of passed Lessons.
    ''' Used to examine if a certification was completely satisfied
    ''' </summary>
    ''' <remarks></remarks>
    Public Class StudentSatisfiedCertReqs
        Implements IStudentSatisfiedCertReqs

        ''' <summary>
        ''' the certifications provider, ie the class that has the reponsibility to 
        ''' retrieve from the database the passed certifications of a student
        ''' </summary>
        ''' <remarks></remarks>
        Private _certificationSatisfiedRequirementProvider As ICertificationSatisfiedRequirementProvider

        ''' <summary>
        ''' The student we are working on...
        ''' </summary>
        Protected _student As Student

        ''' <summary>
        ''' The Period we are working on...
        ''' </summary>
        Protected _period As Period

        ''' <summary>
        ''' The _certification type we are examining
        ''' </summary>
        Protected _certificationType As CertificationType

        ''' <summary>
        ''' List of requirements satisfied by this student and this certification type
        ''' This is basically a list of CertificationSatisfiedRequirements
        ''' </summary>
        Protected Property studentSatisfiedRequirements As  _
                Dictionary(Of Integer, CertificationSatisfiedRequirement)

        Public ReadOnly Property Student As Student _
                            Implements IStudentSatisfiedCertReqs.Student

            Get
                Return _student
            End Get

        End Property

        Public ReadOnly Property period As Period _
                                       Implements IStudentSatisfiedCertReqs.Period
            Get
                Return _period
            End Get

        End Property

        Public ReadOnly Property certificationType As CertificationType _
                                        Implements IStudentSatisfiedCertReqs.certificationType
            Get
                Return _certificationType
            End Get

        End Property

        Public Sub New(ByVal processPeriod As Period, ByVal student As Student, ByVal certType As CertificationType)

            Me._student = student
            Me._certificationType = certType
            Me._period = processPeriod

        End Sub

        ''' <summary>
        ''' load Student Satisfied Requirements from passed periods
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub LoadStudentSatisfiedRequirementsFromPassedPeriods() _
            Implements IStudentSatisfiedCertReqs.LoadStudentSatisfiedRequirementsFromPassedPeriods

            Dim lst As List(Of CertificationSatisfiedRequirement) = _
                Me.CertificationSatisfiedRequirementProvider. _
                    getStudentCertificationSatisfiedRequirement(Me.period, _
                        Me.certificationType, _
                        Me.Student)

            Me.studentSatisfiedRequirements = _
                    New Dictionary(Of Integer, CertificationSatisfiedRequirement)

            For Each csr As CertificationSatisfiedRequirement In lst
                'check if the dictionary already has a CertificationRequirementId, ie the student
                'has passed the class before.  If so, we choose the one with the higher grade
                Dim certKey As Integer = csr.CertificationRequirementId.GetValueOrDefault

                If Me.studentSatisfiedRequirements.ContainsKey(certKey) Then
                    'here we check if the satisfied req we are working on has a higher grade
                    'first check csr.ClassMemberId IsNot Nothing because csr.ClassMember loads a new instrance
                    If csr.ClassMemberId IsNot Nothing AndAlso csr.ClassMember.Grade.GetValueOrDefault > _
                            CType(Me.studentSatisfiedRequirements.Item(certKey),  _
                                CertificationSatisfiedRequirement).ClassMember.Grade.GetValueOrDefault Then

                        Me.studentSatisfiedRequirements.Remove(certKey)
                        Me.studentSatisfiedRequirements.Add(certKey, csr)
                    End If
                Else
                    Me.studentSatisfiedRequirements.Add(certKey, csr)
                End If

            Next
        End Sub

        Public Sub addSatifiedRequirement(ByVal certReq As CertificationSatisfiedRequirement) _
                Implements IStudentSatisfiedCertReqs.addSatifiedRequirement

            If Me.studentSatisfiedRequirements Is Nothing Then

                'if we are dealing with a DAS period, also load all DAS certifications.
                'This is for the case of member number 575, where he passed exams for 2 certificates 
                '
                Me.LoadStudentSatisfiedRequirementsFromPassedPeriods()

            End If

            'add to the list of satisfied requirements using the CertificationRequirementId as the key of the dictionary collection
            If Not Me.studentSatisfiedRequirements.ContainsKey(certReq.CertificationRequirementId.GetValueOrDefault) Then
                Me.studentSatisfiedRequirements.Add(certReq.CertificationRequirementId.GetValueOrDefault, certReq)
            End If

        End Sub

        ''' <summary>
        ''' checks if all the satisfied requirements have satisified the conditions that the student must fullfill
        ''' in order to earn a certificate
        ''' </summary>
       Public Overridable Function isCertificationEarned() As Boolean _
                        Implements IStudentSatisfiedCertReqs.isCertificationEarned

            If Me.Student.MemberNumber = PeriodProcessor.TRACK_STUDENT_NUMBER Then
                Trace.TraceInformation("Member Number: {0} Check Certificate: {1}", _
                                 Me.Student.MemberNumber, Me.certificationType.CertificationType)
            End If
            Dim passed As Boolean = True
            'loop thru each certification requirement of the certificate I am looking to see if the student passed it
            For Each cr As CertificationRequirement In Me.certificationType.CertificationRequirements

                If Me.studentSatisfiedRequirements.ContainsKey(cr.CertificationRequirementId) = False Then
                    'if CertificationRequirementId is not included in the collection of satisfied requirements,
                    'then we just exit and return false
                    If Me.Student.MemberNumber = PeriodProcessor.TRACK_STUDENT_NUMBER Then
                        Trace.TraceInformation("Member Number: {0} CertificateRequirement NOT PASSED: {1}, missing CertificationRequirementId:{2} Lessons: {3},{4},{5}", _
                                         Me.Student.MemberNumber, Me.certificationType.CertificationType, _
                                         cr.CertificationRequirementId, _
                                         cr.LessonCode,
                                         cr.RequiredAlternativeLesson.LessonCode,
                                         cr.RequiredAlternativeLesson1.LessonCode)
                    End If

                    ModelContext.CurrentDBUtils.executeSQLWithParams(<sql>
if not exists (select * from [DASMissingRequirements] where studentid ={0} and LessonId={1})
insert into [DASMissingRequirements] (StudentId,LessonId)
SELECT     a.StudentId, {1}
FROM  DASExpectedHolders AS d ,Student AS a 
where d.MemberNumber = a.MemberNumber
and	a.StudentId={0} </sql>.Value, Student.StudentId, cr.LessonId)

                    passed = False
                End If

            Next

            If Not passed Then
                Return False
            End If

            'if we make it here the it means that all CertificationRequirement were satisfied
            If Me.Student.MemberNumber = PeriodProcessor.TRACK_STUDENT_NUMBER Then
                Trace.TraceInformation("{0} {1} Member Number: {2} passed certification: {3}", _
                                 Me.period.PeriodCode, Me.period.DiplomaSuperType.DiplomaSuperTypeCode, Me.Student.MemberNumber, Me.certificationType.CertificationType)
            End If

            'set all satisfied requirements' flag isUsedForCertification to true
            Me.studentSatisfiedRequirements.Values.ToList.ForEach(Sub(x)
                                                                      'see DBProcessorPersistor where we use this flag
                                                                      'we use it because we do not want to save 
                                                                      'ExceptionSatisfiedRequirements unless they are 
                                                                      'actually used for a certification
                                                                      x.isUsedForCertification = True

                                                                  End Sub)



            Return True

        End Function

        Public ReadOnly Property SatisfiedRequirements As List(Of CertificationSatisfiedRequirement) _
                        Implements IStudentSatisfiedCertReqs.SatisfiedRequirements

            Get
                Return Me.studentSatisfiedRequirements.Values.ToList
            End Get
        End Property


        Public Property CertificationSatisfiedRequirementProvider() _
                    As ICertificationSatisfiedRequirementProvider
            Get

                If _certificationSatisfiedRequirementProvider Is Nothing Then
                    If _period.DiplomaSuperTypeId = EnumDiplomaSuperTypes.DAS Then
                        _certificationSatisfiedRequirementProvider = New CertifSatisfiedReqsProviderDAS
                    Else
                        _certificationSatisfiedRequirementProvider = New CertifSatisfiedReqsProvider
                    End If

                End If

                Return _certificationSatisfiedRequirementProvider
            End Get
            Set(ByVal value As ICertificationSatisfiedRequirementProvider)
                _certificationSatisfiedRequirementProvider = value
            End Set
        End Property


    End Class
End Namespace
